package com.itheima.service.impl;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.itheima.common.CommonResult;
import com.itheima.dto.PhoneCodeDto;
import com.itheima.mapper.UserMapper;
import com.itheima.pojo.User;
import com.itheima.service.UserService;
import com.itheima.vo.LoginVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PutMapping;

import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * @author YangJiaHao
 */
@Service
@Slf4j
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Override
    public Boolean sendMsg(String phone) {
        // 生成验证码
        int number = new Random().nextInt(100000) + 100000;

        log.info("验证码：{}", number);
        // 存到Redis
        redisTemplate.opsForValue().set("CODE" + phone, number + "", 2L, TimeUnit.HOURS);


        return true;
    }

    @Override
    public LoginVo login(PhoneCodeDto phoneCodeDto) {
        // 1校验入参
        if (phoneCodeDto == null || StringUtils.isEmpty(phoneCodeDto.getCode()) || StringUtils.isEmpty(phoneCodeDto.getPhone())) {
            throw new RuntimeException("入参不能为空");
        }

        String phone = phoneCodeDto.getPhone();
        // 2.校验验证码
        // 2.1 从Redis读取发送的验证码
        String codeFromRedis = redisTemplate.opsForValue().get("CODE" + phone);
        if (StringUtils.isEmpty(codeFromRedis)) {
            throw new RuntimeException("验证码不存在");
        }
        // 2.2 从dto中读取用户输入的验证码
        String code = phoneCodeDto.getCode();
        // 2.3 比较两个验证码
        if (!code.equals(codeFromRedis)) {
            throw new RuntimeException("验证码错误");
        }

        // 3 检测手机号是否存在
        // 3.1 创建用户的实体类
        // 3.2 调用mapper的selectByPhone
        User user = userMapper.selectByPhone(phone);
        // 4 如果不存在，则创建账号，再生产token并写入Redis
        if (user == null) {
            // 4.1 组装user对象
            User newUser = new User();
            newUser.setId(IdUtil.getSnowflakeNextIdStr());
            newUser.setName("用户" + System.currentTimeMillis());
            newUser.setPhone(phone);
            newUser.setGender("男");
            newUser.setIdNumber("111111");
            newUser.setAvatar("111111");
            newUser.setStatus(1);
            // 4.2 调用mapper.insertUser
            Integer result = userMapper.insertUser(newUser);
            if (result != 1) {
                throw new RuntimeException("注册失败");
            }
            user = new User();
            BeanUtils.copyProperties(newUser, user);
        }
        // 5 如果存在，则生成token并写入Redis
        // 5.1 生成token(无规则，唯一)
        String token = "user_token" + System.currentTimeMillis();
        // 5.2 存入redis
        // 如果想把一个对象存到Redis，最好转成json再存进去（fastJson）
        redisTemplate.opsForValue().set("user_token:" + token, JSON.toJSONString(user));
        // 5.3 组装返回值的vo结构
        LoginVo loginVo = new LoginVo();
        loginVo.setId(user.getId());
        loginVo.setPhone(user.getPhone());
        loginVo.setStatus(user.getStatus());
        loginVo.setToken(token);

        return loginVo;
    }

    @Override
    public void clearToken(String token) {
        Boolean res = redisTemplate.hasKey("user_token:" + token);
        if (res == true) {
            redisTemplate.delete("user_token:" + token);
        }
    }


}
